package com.moxiao.yfjh.module.order.api;

import cn.hutool.extra.spring.SpringUtil;
import com.moxiao.yfjh.framework.common.util.number.NoCommonUtil;
import com.moxiao.yfjh.module.activity.common.ActivityNotifyMessageUtils;
import com.moxiao.yfjh.module.activity.controller.admin.activityEnroll.vo.ActivityEnrollQueryVO;
import com.moxiao.yfjh.module.activity.controller.admin.activityEnroll.vo.ActivityEnrollRespVO;
import com.moxiao.yfjh.module.activity.convert.activityEnroll.ActivityEnrollConvert;
import com.moxiao.yfjh.module.activity.dal.dataobject.activityEnroll.ActivityEnrollDO;
import com.moxiao.yfjh.module.activity.dal.dataobject.activityInfo.ActivityInfoDO;
import com.moxiao.yfjh.module.activity.service.activityEnroll.ActivityEnrollService;
import com.moxiao.yfjh.module.activity.service.activityInfo.ActivityInfoService;
import com.moxiao.yfjh.module.order.common.GenNoCommonUtil;
import com.moxiao.yfjh.module.order.controller.admin.blindTradeRefund.vo.BlindTradeRefundCreateReqVO;
import com.moxiao.yfjh.module.order.convert.blindTradeRefund.BlindTradeRefundConvert;
import com.moxiao.yfjh.module.order.dal.dataobject.blindTradeRefund.BlindTradeRefundDO;
import com.moxiao.yfjh.module.order.dal.mysql.blindTradeRefund.BlindTradeRefundMapper;
import com.moxiao.yfjh.module.order.tradeRefund.TradeRefundApiDTO;
import com.moxiao.yfjh.module.order.tradeRefund.TradeRefundApiService;
import com.moxiao.yfjh.module.pay.api.refund.dto.PayRefundCreateReqDTO;
import com.moxiao.yfjh.module.pay.dal.dataobject.app.PayAppDO;
import com.moxiao.yfjh.module.pay.dal.dataobject.order.PayOrderDO;
import com.moxiao.yfjh.module.pay.service.app.PayAppService;
import com.moxiao.yfjh.module.pay.service.order.PayOrderService;
import com.moxiao.yfjh.module.pay.service.refund.PayRefundService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;

import static com.moxiao.yfjh.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.moxiao.yfjh.module.activity.enums.ErrorCodeConstants.*;

/**
 * 活动退款Api
 */
@Slf4j
@Service
@Validated
public class TradeRefundApiServiceImpl implements TradeRefundApiService {
    @Resource
    private BlindTradeRefundMapper blindTradeRefundMapper;
    @Resource
    private ActivityInfoService infoService;
    @Resource
    private ActivityEnrollService enrollService;
    @Resource
    private GenNoCommonUtil genNoCommonUtil;
    @Resource
    private ActivityNotifyMessageUtils messageUtils;
    @Resource
    private PayOrderService payOrderService;
    @Resource
    private PayAppService payAppService;
    @Resource
    private PayRefundService payRefundService;

    /**
     * 未开始非发起者
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void notStarted(TradeRefundApiDTO appRefund) {
        ActivityInfoDO info = infoService.getInfo(appRefund.getActivityId());
        if (Objects.nonNull(info)) {
            ActivityEnrollQueryVO reqVO = new ActivityEnrollQueryVO();
            reqVO.setActivityId(appRefund.getActivityId());
            reqVO.setActivityStatus((byte) 1);
            List<ActivityEnrollDO> enrollDOList = enrollService.selectEnrollList(reqVO);
            if (!enrollDOList.isEmpty()) {
                enrollDOList.forEach(item -> {
                    enrollService.updatePayStatus(item.getId(), (byte) 2);
                    if (item.getPayAmount().compareTo(BigDecimal.ZERO) > 0) {
                        //TODO 添加退款记录
                        BlindTradeRefundCreateReqVO refundCreate = new BlindTradeRefundCreateReqVO();
//                        int fenAmount = item.getPayAmount().multiply(new BigDecimal(100)).intValue();
//                        BigDecimal newYuanAmount = new BigDecimal(fenAmount).divide(new BigDecimal(100));
                        refundCreate.setRefundPrice(item.getPayAmount());
                        //TODO 创建相亲业务的退款记录
                        refundCreate.setUserId(item.getUserId());
                        refundCreate.setActiveNo(info.getNo());
                        refundCreate.setActiveName(info.getName());
                        refundCreate.setOrderId(item.getId());
                        refundCreate.setOrderNo(item.getNo());
                        refundCreate.setApplyDescription("本次活动参与人员已满，您已被退出活动，");
                        refundCreate.setStatus(0);
                        genNoCommonUtil.addRefundNo(refundCreate);
                        refundCreate.setApplyReason("活动报名退款");
                        Long refundId = createBlindTradeRefund(refundCreate);
                        //TODO 创建系统的退款单，并发起退款
                        // getSelf().createPayRefund(item,refundId);
                        //TODO 创建活动通知
                        ActivityEnrollRespVO enrollRespVO = ActivityEnrollConvert.INSTANCE.convert(item);
                        enrollRespVO.setActivityName(info.getName());
                        enrollRespVO.setActivityId(info.getId());
                        messageUtils.createActivityEnrollMessage(enrollRespVO);
                        enrollService.updatePayStatus(item.getId(), (byte) 2);
                    } else {
                        enrollService.updatePayStatus(item.getId(), (byte) 2);
                    }
                    // 将未开始的活动状态修改为可报名
                    if (info.getStatus() == 3) {
                        infoService.updateByStatus(info.getId(), (byte) 2);
                    }
                });
            }
        } else {
            throw exception(ENROLL_NO_RELATED_ACTIVITIES_FOUND_NOT_EXISTS);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public Long createBlindTradeRefund(BlindTradeRefundCreateReqVO createReqVO) {
        // 插入
        BlindTradeRefundDO blindTradeRefund = BlindTradeRefundConvert.INSTANCE.convert(createReqVO);

        blindTradeRefundMapper.insert(blindTradeRefund);
        // 返回
        return blindTradeRefund.getId();
    }


    /**
     * 相亲业务-创建退款支付单
     *
     * @param enrollDO
     */
    @Transactional(rollbackFor = Exception.class)
    public void createPayRefund(ActivityEnrollDO enrollDO, Long refundId) {
        log.info("创建报名退款========{}", enrollDO);
        // 创建退款单
        PayRefundCreateReqDTO createReqDTO = new PayRefundCreateReqDTO();
        // 获得相亲app的id
        PayAppDO payAppDO = payAppService.getApp(9L);
        if (Objects.nonNull(payAppDO)) {
            createReqDTO.setAppId(payAppDO.getId());
        } else {
            throw exception(PAY_REFUND_ORDER_EXISTS);
        }
        // 查找支付订单
        PayOrderDO payOrderDO = payOrderService.getPayOrder(enrollDO.getId(), 2, enrollDO.getUserId().toString());
        if (Objects.nonNull(payOrderDO)) {
            createReqDTO.setMerchantOrderId(NoCommonUtil.getUuid(payOrderDO.getId().toString()).toString());
            createReqDTO.setMerchantRefundId(String.valueOf(refundId));
        } else {
            throw exception(PAY_ORDER_NOT_NULL_EXISTS);
        }
        createReqDTO.setUserIp(enrollDO.getUserId().toString());
        createReqDTO.setReason("活动退款，活动报名退款");
        // 创建退款单,并发起退款
        Long payRefundId = payRefundService.createPayRefund(createReqDTO);
        log.info("活动报名退款结束========{}", payRefundId);
    }

    /**
     * 获得自身的代理对象，解决 AOP 生效问题
     *
     * @return 自己
     */
    private TradeRefundApiServiceImpl getSelf() {
        return SpringUtil.getBean(getClass());
    }

}
